React 小笔记

React 小笔记

  1. react 组件一定需要一个根元素,Fragment 占位符可以代替 html 标签而不渲染出标签

  2. Constructor 里面的 state 负责存储组件里面的数据

  3. jsx 里面使用如果需要使用 js 的表达式,需要使用花括号’{}’括起来

  4. 事件绑定的时候,需要使用 bind(this) 对函数的作用域进行变更

  5. 如果需要改变 state 数据项的内容,不能直接修改,需要通过 setState 向里面传入一个对象的方式进行修改

  6. react 中有个概念叫 immutable, state 不允许我们做任何改变,所以一般我们都是修改引用类型的副本,再进行赋值操作

  7. jsx 中注释的写法: {/ 注释内容 /} 和 { // 注释内容 },第二种写法是单行注释,需要把注释和 {} 换行,即 ‘{‘ 一行, 注释内容一行, ‘}’ 一行

  8. jsx 中定义 class 类名需要写成 className

  9. jsx 中想要不转义 html 标签,使用 dangerouslySetInnerHTML={__html: item}, 类似于 vue 中的 v-html

  10. 在 jsx 中使用 html 中的点击 label 聚焦功能,在 label 中使用 for 对应 input 中的 id 会报警告,需要使用 htmlFor 代替 for,这样不会和 for 循环产生歧义。

  11. 父组件通过属性的方式向子组件传递数据,子组件通过 this.props.xxx来获取父组件传递过来的属性内容,包括方法。

  12. TodoItem.propTypes = {} 可以用于在父子组件传值中,在子组件中设置传递数据的数据类型:

1
2
3
4
5
6
TodoItem.propTypes = {
test: PropTypes.string.isRequired,
content: PropTypes.string,
deleteItem: PropTypes.func,
index: PropTypes.number
}
  1. TodoItem.defaultProps = {} 可以用于在父子组件传值中,在子组件中设置传递数据的默认值:
1
2
3
TodoItem.defaultProps = {
test: 'hello world'
}
  1. 当组件的 state 或者 props 发生改变的时候,render 函数就会重新执行,进行页面的渲染,可以在子组件的生命周期函数 shouldComponentUpdate 中优化和控制是否渲染
1
2
3
4
5
6
7
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.content !== this.props.content) {
return true
} else {
return false
}
}
  1. 当父组件的 render 函数被运行时,它的子组件的 render 都将重新被运行一次

  2. react 中引入虚拟dom提高性能的原因是:减少了对真是dom的创建,以及真实dom的对比,取而代之创建的是js对象,对比的也是js对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. state 数据
2. JSX 模板
3. 数据 + 模板 生成虚拟 DOM (虚拟DOM就是一个JS对象,用它来描述真是的DOM)
['div', {id: 'abc'}, ['span', {}, 'hello world']]
4. 用虚拟DOM的结构生成真是的DOM来显示,(JSX ->(通过createElement方法) JS 对象 -> 真实的DOM)(损耗了性能)
<div id='abc'><span>hello world</span></div>
5. state 发生变化
6. 数据 + 模板生成新的虚拟DOM (极大的提升了性能)
['div', {id: 'abc'}, ['span', {}, 'bye bye']]
7. 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中内容(极大的提升行能)
8. 直接操作DOM,改变span中的内容

优点:
1. 性能提升
2. 它使得跨端应用得以实现。React Native
  1. 循环中,能用稳定的属性作为 key 值,则不要用 index 作为 key 值,这样能充分发挥 key 值的作用:提高虚拟 DOM 的比对行能。

  2. 在虚拟DOM的比对中,是逐层进行的,如果有一层不同,则下一层将不会再进行比对,直接废弃用新的替换旧的。

  3. react 里面使用 ref: <ul ref={(ul) => {this.ul = ul}}></ul>, 后续在js代码中通过 this.ul 获取 ul 的 dom 对象

  4. 对应 VUE 中的 this.$nextTick() 函数,react 中的操作是在 setState 后有一个回调函数来进行对DOM的获取和操作

1
2
3
4
5
6
this.setState((prevState) => ({
list: [...prevState.list, prevState.inputValue],
inputValue: ''
}), () => {
console.log(this.ul)
})
  1. react 的生命周期:

    1. Initialization: setup props and state
    2. Mounting: componentWillMount -> render -> componentDidMount(类似于Vue中的beforeMount 和 Mounted)
    3. Updation:
      1. props改变:componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate
      2. states改变:shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate
    4. Unmounting: componentWillUnmount
  2. 在 componentDidMount 钩子中进行数据请求,可以利用Charles做前端数据Mock

  3. react 中最基础的动画操作就是通过改变 DOM 元素的类名:<div className={this.state.show ? 'show' : 'hide'}></div>

  4. react 中的 Transition 组件不是内置的,需要引用 React Transition Group 这个库,使用方式和 vue 中类似

  5. 单纯只有一个 render 函数的组件称之为 UI 组件,存在其他生命周期函数的组件为容器组件,UI 组件可以做成无状态组件,从而取得更好的性能,因为单纯是一个函数,不需要执行生命周期 相关的各种函数。

  6. 使用 Redux-thunk 中间件进行 ajax 请求,只使用 redux 的情况下,action 只能是一个对象,但是使用 Redux-thunk 后,action 可以是一个函数,并且函数的回调带有 dispatch 方法,可以直接 dispatch 相关需要派发给 store 的 action,然后 store 把 action 和之前的 state 一起传递给 Reducer , Reducer 返回一个新的数据给 store,store 去改变自己的 state。

  7. Redux 中间件的中间指的是 Action 和 Store 之间,Redux-thunk、Redux-saga 等中间件是对 Dispatch 进行了封装和升级。

  8. 利用 React-redux 中的 Provider 连接 react 中的组件,可以不用 this.state = store.getState() 来获取 store 里面的数据,而可以这样用:

1
2
3
4
5
6
7
8
9
10
11
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import TodoList from './TodoList'
import { Provider } from 'react-redux'
import store from './store'
const APP = (
<Provider store={store}>
<TodoList/>
</Provider>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// TodoList.js
...
import { connect } from 'react-reduct'
...
// 导出方式修改
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue
}
}
const mapDispatchToProps = (dispatch) => {
return {
changeInputValue(e) {
const action = {
type: 'change_input_value',
value: e.target.value
}
dispatch(action)
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoList)